package com.core.email;

import com.common.utils.Constants;
import com.common.redis.RedisCache;
import com.common.utils.DateUtils;
import com.common.utils.StringUtils;
import com.common.utils.Utils;
import com.core.email.model.EmailCode;
import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MessageFormatter;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class EmailService {

    @Resource
    private JavaMailSender javaMailSender;

    @Resource
    private RedisCache redisCache;


    private static String moba="<div class=\"mail-container\" style=\"width: 100%;background-color: #EEEEEE; padding: 20px; color:#333333;\">\n" +
            "    <div class=\"mail\" style=\"width: 600px;background-color: #FFFFFF;margin: 0 auto;margin-bottom: 40px;\">\n" +
            "        <div class=\"logo-box\" style=\"height: 90px;border-bottom: 1px solid #EEEEEE; padding: 26px;box-sizing: border-box;text-align: center; position: relative;\">\n" +
            "            <img src=\"https://image.aeroz.cn/images/2021/07/22/company_logo.png\" style=\"height:38px\" alt=\"LOGO\">\n" +
            "        </div>\n" +
            "        <div class=\"content-box\" style=\"padding: 20px 50px; font-size: 14px;\">\n" +
            "            <p class=\"hello\" style=\"color: #950013; text-align: center;margin-top: 0;;margin-bottom: 20px;\">您好</p>\n" +
            "            <p>有人正在尝试验证操作。</p>\n" +
            "            <p>请输入以下代码完成验证：</p>\n" +
            "            <div class=\"code\" style=\"padding: 5px;background-color: #FAF9FA; border: 1px solid #DAD8DE;font-size: 24px;text-align: center;line-height: 1.8;\">\n" +
            "                {}\n" +
            "            </div>\n" +
            "            <p style=\"margin-top: 5px;margin-bottom: 20px;text-align: center;font-size: 12px;font-weight: bold;\">请注意此代码将于 {} 失效。</p>\n" +
            "            <p>如果此次登录并非您的操作，请立即更改您的密码以保障账户安全</p>\n" +
            "            <div style=\"margin-bottom: 20px;\">\n" +
            "                <p>如果代码无法正常工作，请申请新的验证码，并尝试以下问题排查步骤：</p>\n" +
            "                <ul>\n" +
            "                    <li>使用浏览器的隐身模式，或更换其他浏览器</li>\n" +
            "                    <li>清理浏览器缓存和 Cookie，并禁用任何浏览器插件或扩展程序</li>\n" +
            "                </ul>\n" +
            "            </div>\n" +
            "            <p style=\"margin:0;\">谢谢，</p>\n" +
            "            <p style=\"margin:0;\">XXX支持团队</p>\n" +
            "        </div>\n" +
            "    </div>\n" +
            "    <div style=\"text-align: center; font-size:14px; color:#706a7c;\">\n" +
            "        <p style=\"margin:0;\">© 2021 XXXX 保留所有权利。</p>\n" +
            "        <p style=\"margin:0;\">XXX</p>\n" +
            "    </div>\n" +
            "</div>";

    public String setMessage(String... appendLogArguments){
        FormattingTuple ft = MessageFormatter.arrayFormat(moba, appendLogArguments);
       return ft.getMessage();
    }

    /**
     * @Author: zql
     * @Description: 发送邮箱验证码
     * @param email
     * @Data: 11:39 2021/7/22
     */
    public void sendCode(String email) {
        String code = Utils.vCode();
        //保存邮箱验证码到redis
        EmailCode emailCode= CreateEmailCode(email,code);
        //发送邮件
        sendEmail("您的验证码", setMessage(code, DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,new Date(emailCode.getExpireTime()))), true, null, new String[]{email});
    }

    /**
     * @Author: zql
     * @Description: 使用redis缓存记录手机验证码
     * @param email 邮箱
     * @param code 验证码
     * @Data: 8:59 2021/7/13
     */
    private EmailCode CreateEmailCode(String email, String code) {
        String key = getEmailCodeKey(email);
        EmailCode emailCode = redisCache.getCacheObject(key);
        if (StringUtils.isNull(emailCode)) {
            emailCode = new EmailCode();
            emailCode.setEmail(email);
            emailCode.setCodes(new HashSet<>());
        }
        emailCode.getCodes().add(code);
        refresh(emailCode);
        return emailCode;
    }

    /**
     * @Author: zql
     * @Description: 刷新邮箱的验证码有效期
     * @param emailCode 邮箱验证码存储的对象
     * @Data: 9:02 2021/7/13
     */
    private void refresh(EmailCode emailCode) {
        String key = getEmailCodeKey(emailCode.getEmail());
        emailCode.setLoginTime(System.currentTimeMillis());
        emailCode.setExpireTime(emailCode.getLoginTime() + EmailConfig.getExpireTime()* Constants.MINUTE_MILLIS);
        redisCache.setCacheObject(key, emailCode, EmailConfig.getExpireTime(), TimeUnit.MINUTES);
    }

    /**
     * @Author: zql
     * @Description: 校验验证码是否正确
     * @param email 邮箱
     * @param emailCode 需校验的验证码
     * @Data: 9:05 2021/7/13
     */
    public boolean check(String email, String emailCode) {
        String key = getEmailCodeKey(email);
        EmailCode emailCodeObj = redisCache.getCacheObject(key);
        if (emailCodeObj == null || !emailCodeObj.getCodes().contains(emailCode)) {
            return false;
        }
        redisCache.deleteObject(key);
        return true;
    }

    /**
     * @Author: zql
     * @Description: 获取邮箱验证码关键字key
     * @param email 发送人邮箱
     * @Data: 11:10 2021/7/22
     */
    private String getEmailCodeKey(String email) {
        StringBuffer str = new StringBuffer();
        str.append(Constants.EMAIL_CODE_KEY).append(email);
        return str.toString();
    }

    /**
     * @Author: zql
     * @Description: 检查剩余有效时间
     * @param email 邮箱
     * @Data: 9:02 2021/7/13
     */
    public long countDown(String email) {
        String key = getEmailCodeKey(email);
        EmailCode emailCode = redisCache.getCacheObject(key);
        if (emailCode == null) {
            return 0;
        }
        //过期时间
        long expireTime = emailCode.getExpireTime();
        //当前时间
        long currentTime = System.currentTimeMillis();
        //剩余时间
        long effectiveTime = (expireTime - currentTime);
        //把剩余时间转换成秒
        effectiveTime = effectiveTime / Constants.SECOND_MILLIS;
        //距离上次发送验证码已经经过的时间（秒）
        long second = EmailConfig.getExpireTime() * Constants.MINUTE_MILLIS / Constants.SECOND_MILLIS - effectiveTime;
        //距离下次发送剩余时间
        long countDown = EmailConfig.getInterval() - second;
        return countDown < 0 ? 0 : countDown;
    }

    public void sendEmail(String subject,String text,boolean isHtml,File[] attachment, String[] addresses) {
        // 文本发送
        // MimeMessage 本身的 API 有些笨重，我们可以使用 MimeMessageHelper
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            // 第二个参数是 true ，表明这个消息是 multipart类型的/
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
            //发送人
            mimeMessageHelper.setFrom(EmailConfig.getUsername());
            List<String> addressList = new ArrayList<>(Arrays.asList(addresses));
            //邮件必须给自己抄送一遍，否则可能会报垃圾邮件无法发送
            addressList.add(EmailConfig.getUsername());
            String[] newArr = addressList.toArray(new String[0]);
            mimeMessageHelper.setTo(newArr);
            //主题
            mimeMessageHelper.setSubject(subject);
            if (isHtml) {
                mimeMessageHelper.setText("html格式", text);
            } else {
                mimeMessageHelper.setText(text);
            }
            if (attachment != null && attachment.length > 0) {
                for (File file : attachment) {
                    mimeMessageHelper.addAttachment(file.getName(), file);
                }
            }
            javaMailSender.send(mimeMessage);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}
